package com.mmall.common;

import com.mmall.exception.ParamException;
import com.mmall.exception.PermissionException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 全局异常处理类
 * 注意： 需要在spring配置里面去配置这个Bean
 * <bean class="com.mmall.common.SpringExceptionResolver" />
 * 核心业务逻辑的时候需要有必要的日志输出
 */
@Slf4j
public class SpringExceptionResolver implements HandlerExceptionResolver {
    /**
     * 异常处理逻辑
     * @param request：请求
     * @param response：响应
     * @param handler：异常的处理对象
     * @param ex：抛出的异常
     * @return modelAndView: 返回指定的jsp页面
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        String url = request.getRequestURL().toString();
        ModelAndView mv;
        //默认的异常信息
        String defaultMsg = "System error";
        // 这里我们要求项目中所有请求json数据，都使用.json结尾 --> 判断页面请求还是json请求
        if (url.endsWith(".json")) {
            //如果当前的异常是自定义异常，msg使用的就是异常的message
            if (ex instanceof PermissionException || ex instanceof ParamException) {
                JsonData result = JsonData.fail(ex.getMessage());
                //jsonView 返回json 数据
                //<!-- 与json 返回的时候，以它来做处理 --> spring-servlet.xml 中有jsonView的实例化对象 由它来处理
                //<bean id="jsonView" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
                mv = new ModelAndView("jsonView", result.toMap());
                //如果不是就使用默认跑出来的异常defaultMsg
            } else {
                //非自定义异常，记录下异常记录下url记录堆栈
                log.error("unknown json exception, url:" + url, ex);
                JsonData result = JsonData.fail(defaultMsg);
                mv = new ModelAndView("jsonView", result.toMap());
            }
        } else if (url.endsWith(".page")){ // 这里我们要求项目中所有请求page页面，都使用.page结尾
            //非自定义异常，记录下异常记录下url记录堆栈
            log.error("unknown page exception, url:" + url, ex);
            JsonData result = JsonData.fail(defaultMsg);
            //ModelAndView 会去定义的 jsp页面下面寻找一个名字叫exception.jsp的页面
            /**
             * <!-- jsp 的视图解析器 如果以Jsp返回以它来做处理-->
             * <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
             *   <property name="prefix" value="/WEB-INF/views/" />
             *   <property name="suffix" value=".jsp" />
             * </bean>
             */
            mv = new ModelAndView("exception", result.toMap());
        } else { //非json与非.page结尾的处理，默认的异常处理
            //非自定义异常，记录下异常记录下url记录堆栈
            log.error("unknown exception, url:" + url, ex);
            JsonData result = JsonData.fail(defaultMsg);
            mv = new ModelAndView("jsonView", result.toMap());
        }
        return mv;
    }
}
